WF Prediction¶
using MOD14A1.061: Terra Thermal Anomalies & Fire Daily Global 1km
THEORETICAL DESCRIPTION
The MODIS fire detection and characterisation techniques are fully automated for the production of daily, global fire information. In order to detect the presence of fire in a noninteractive fashion, a set of detection criteria different
for the day and night fire observations are prescribed. These multipsectral criteria are based on the apparent temperature
of the fire pixel and the difference between the fire pixel and its background temperature.
MOD14A1andMYD14A1¶
The MOD14A1 and MYD14A1 daily Level 3 fire products are tile-based, with each product file spanning one of the 460 MODIS tiles, of which 326 contain land pixels. The product is a 1-km gridded composite of fire pixels detected in each grid cell over each daily(24-hour)compositing period. Forconvenience, eight days of data are packaged into a single file.
Fire Mask¶
FireMask Thefiremaskisstoredasan8(orless)×1200×1200,8-bitunsignedintegerSDSnamed“FireMask”. (Forhistoricalreasonsthislayerwasnamed“mostconfidentdetectedfire”priortoCollection5.)TheSDScontainseightsuccessivedailyfiremasksforaspecificMODIStile.Eachofthese dailymasks isessentiallyamaximumvaluecomposite3of theLevel2fireproductpixelclasses (Table3)forthoseswathsoverlappingtheMODIStileduringthatday.Productfilescontainingless thaneightdaysofdatawilloccasionallybeencounteredduringtimeperiodsofmissingdataand shouldbehandlediningestsoftware.
QA¶
Eachof thedailyfiremaskshasacorrespondingsimpleQAlayer. Eachlayer isa1200×1200 8-bitunsignedintegerarray.OnlysevenuniqueQAvaluesarepossible,withthemeaningsshown inTable7.Notethatformissing-datagridcells(bitpattern11inbits0-1),bit2willalwaysbeclear. Table7:QAvaluesintheCollection6MODISLevel3tiledactivefireproducts. Bit(s) Meaning 0-1 land/waterstate(00=water,01=coast,10=land,11=missingdata) 2 day/nightobservation(0=night,1=day)
MaximumFRP¶
Themaximumfireradiativepowerofallfirepixelsfallingwithineachgridcell isprovidedona dailybasis inthe“MaxFRP”SDS.HeretheFRPvalueshavebeenscaledbyafactorof10and storedasa32-bitsignedinteger.Multiplythesescaledvaluesby0.1toretrievethemaximumFRP inMW.
import geopandas as gpd
import json
import geemap
import ee
import folium
ee.Authenticate()
True
# 'MaxFRP' (Maximum Fire Radiative Power): This band represents the maximum fire radiative power detected within the pixel. Fire Radiative Power (FRP) is a measure of the heat output from detected fires. Higher FRP values indicate more intense fires, providing valuable information on the energy being released by fires within the area covered by a pixel. FRP is often used to assess the intensity and potential damage of fires.
# 'FireMask': The FireMask band classifies the land cover in each pixel based on the likelihood of active fire. This classification can include values that represent no fire, fire, water, cloud cover, and more, depending on the specific dataset's coding scheme. Including this band in visualization allows users to differentiate between burning areas and other types of land cover or atmospheric conditions.
# The repeated 'FireMask' in the bands array seems to be an oversight or a placeholder. Typically, you would specify different bands for multi-band visualizations, such as combining red, green, and blue (RGB) bands to produce true or false-color images. However, in the context of fire data visualization, it's more common to focus on specific fire-related metrics like FRP or use the FireMask alone for identifying fire locations.
# For visualizing fire data, one might consider using 'FireMask' to identify fire locations and 'MaxFRP' to assess fire intensity. The repetition of 'FireMask' doesn't add additional information unless there's a specific intent to manipulate the visualization in a way not clearly stated here.
# For more detailed information about the MODIS Fire Product and understanding its bands, you can refer to the official documentation available at the MODIS/061/MOD14A1 dataset page on Google Earth Engine, which provides comprehensive details on each band and their applications.
ee.Initialize()
# Read the shapefile
gdf_2 = gpd.read_file(r"C:\Users\rsingh\OneDrive - PlanRVA\Documents\DataHub-Rishabh\Base locality Boundary\Loc_Boundary_RVA_XY.shp")
# Convert GeoDataFrame to GeoJSON string
gdf_geojson_str = gdf_2.to_json()
# Convert GeoJSON string to dictionary
gdf_geojson_dict = json.loads(gdf_geojson_str)
# Convert GeoJSON dictionary to an Earth Engine object for visualization
ee_geometry = geemap.geojson_to_ee(gdf_geojson_dict)
# # Define the time period
# start_date = '2005-01-01'
# end_date = '2017-05-01'
# Trying latest values
start_date = '2005-01-01'
end_date = '2024-01-01'
ee.Initialize()
# Define the polygon geometry
coordinates = [[
[-78.73462534539406, 36.66846602275374],
[-76.33411265008156, 36.66846602275374],
[-76.33411265008156, 38.376161461825205],
[-78.73462534539406, 38.376161461825205],
[-78.73462534539406, 36.66846602275374]
]]
geometry = ee.Geometry.Polygon(coordinates, None, False)
# start_date = '2005-01-01'
# end_date = '2017-05-01'
# Load the dataset
dataset = ee.ImageCollection('MODIS/061/MOD14A1') \
.filter(ee.Filter.date(start_date, end_date)) \
.filterBounds(geometry)
# Visualization parameters
fire_mask_vis = {
'min': 0.0,
'max': 6000.0,
'bands': ['MaxFRP', 'FireMask', 'FireMask']
}
# Get the centroid of the geometry
centroid = geometry.centroid(maxError=1)
lng_lat = centroid.coordinates()
lng = lng_lat.get(0).getInfo()
lat = lng_lat.get(1).getInfo()
# Use folium or ipyleaflet for visualization in Jupyter notebooks
# Here's an example using folium
import folium
# Create a folium map object.
my_map = folium.Map(location=[lat, lng], zoom_start=2)
# Add the dataset as a layer to the map object.
# Note: folium doesn't directly support ee.Image.
# You must convert it to a tile layer URL using ee.Image.getTileUrl() method.
# The direct addition of Earth Engine layers in folium is a bit more involved and requires
# generating a map ID and token to construct a tile layer URL.
# As an alternative, for actual visualization in Python, consider using the Earth Engine Python API's
# Map display functions or integrating with geemap, a Python package that facilitates mapping Earth Engine data.
# This example focuses on the translation of your GEE JavaScript code to Python,
# so the detailed implementation of map visualization in Python is beyond this scope.
print(f'Centering map at latitude: {lat}, longitude: {lng}')
Centering map at latitude: 37.52108171364334, longitude: -77.53436899773777
# Create an interactive map
print(f"Sample dates: {start_date} to {end_date}")
Map = geemap.Map()
Map.addLayer(dataset, fire_mask_vis, 'Fire Mask')
Map.addLayer(ee_geometry, {}, 'GDF Geometry') ## Overlay layer for area of interest
Map.centerObject(ee_geometry, 9) # Center the map on the geometry with a suitable zoom level
Map
Sample dates: 2005-01-01 to 2024-01-01
Map(center=[37.55953685059643, -77.5161303637407], controls=(WidgetControl(options=['position', 'transparent_b…
Maximum Fire Radioactive Power (MaxFRP): Virginia¶
ee.Initialize()
# Define your geometry here as before
# Define the time period
# start_date = '2005-01-01'
# end_date = '2017-05-01'
# Load the dataset and filter
dataset = ee.ImageCollection('MODIS/061/MOD14A1') \
.filter(ee.Filter.date(start_date, end_date)) \
.filterBounds(geometry)
# Summing the MaxFRP values over the time period to get total fire intensity
summed_frp = dataset.select('MaxFRP').sum()
fire_palette = [
'50A2A7', # Cool water color for no or very low fire intensity
'92C1C1', # Slightly warmer, still low intensity
'D9D678', # A greenish-yellow for low to moderate intensity
'D9AE4B', # Yellow for moderate fire intensity
'D9903D', # Orange for high fire intensity
'D84B2A', # Red-orange for very high fire intensity
'A80000' # Dark red for extreme fire intensity
]
# Define visualization parameters for the summed FRP
summed_frp_vis = {
'min': 0,
'max': 5000, # Adjust this max value based on the range of your summed FRP values
'palette': fire_palette
}
# Centroid for map centering
centroid = geometry.centroid(maxError=1)
lng, lat = centroid.coordinates().getInfo()
# Create a folium map object and center it on the centroid of the geometry
my_map = folium.Map(location=[lat, lng], zoom_start=9)
# Define a function to add Earth Engine layers to folium map
def add_ee_layer(self, ee_image_object, vis_params, name):
map_id_dict = ee.Image(ee_image_object).getMapId(vis_params)
folium.raster_layers.TileLayer(
tiles=map_id_dict['tile_fetcher'].url_format,
attr='Map Data © <a href="https://earthengine.google.com/">Google Earth Engine</a>',
name=name,
overlay=True,
control=True
).add_to(self)
# Add custom method to folium map for adding Earth Engine layers
folium.Map.add_ee_layer = add_ee_layer
# Add the summed FRP layer to the map
my_map.add_ee_layer(summed_frp, summed_frp_vis, 'Summed FRP')
# Add a layer control panel to the map
my_map.add_child(folium.LayerControl())
print(f"Sample dates: {start_date} to {end_date}")
# Display the map
my_map
Sample dates: 2005-01-01 to 2024-01-01
Maximum Fire Radioactive Power (MaxFRP): PlanRVA¶
ee.Initialize()
# Define your geometry here as before
# # Define the time period
# start_date = '2005-01-01'
# end_date = '2018-05-01'
# Load the dataset and filter
dataset = ee.ImageCollection('MODIS/061/MOD14A1') \
.filter(ee.Filter.date(start_date, end_date)) \
.filterBounds(geometry)
# Summing the MaxFRP values over the time period to get total fire intensity
summed_frp = dataset.select('MaxFRP').sum()
fire_palette = [
'50A2A7', # Cool water color for no or very low fire intensity
'92C1C1', # Slightly warmer, still low intensity
'D9D678', # A greenish-yellow for low to moderate intensity
'D9AE4B', # Yellow for moderate fire intensity
'D9903D', # Orange for high fire intensity
'D84B2A', # Red-orange for very high fire intensity
'A80000' # Dark red for extreme fire intensity
]
# Define visualization parameters for the summed FRP
summed_frp_vis = {
'min': 0,
'max': 5000, # Adjust this max value based on the range of your summed FRP values
'palette': fire_palette
}
# Centroid for map centering
centroid = geometry.centroid(maxError=1)
lng, lat = centroid.coordinates().getInfo()
# Create a folium map object and center it on the centroid of the geometry
my_map = folium.Map(location=[lat, lng], zoom_start=9)
# Define a function to add Earth Engine layers to folium map
def add_ee_layer(self, ee_image_object, vis_params, name):
map_id_dict = ee.Image(ee_image_object).getMapId(vis_params)
folium.raster_layers.TileLayer(
tiles=map_id_dict['tile_fetcher'].url_format,
attr='Map Data © <a href="https://earthengine.google.com/">Google Earth Engine</a>',
name=name,
overlay=True,
control=True
).add_to(self)
# Add custom method to folium map for adding Earth Engine layers
folium.Map.add_ee_layer = add_ee_layer
# Add the summed FRP layer to the map
my_map.add_ee_layer(summed_frp, summed_frp_vis, 'Summed FRP')
# Load your GeoDataFrame
gdf_2 = gpd.read_file(r"C:\Users\rsingh\OneDrive - PlanRVA\Documents\DataHub-Rishabh\Base locality Boundary\Loc_Boundary_RVA_XY.shp")
# Convert GeoDataFrame to GeoJSON
gdf_geojson = json.loads(gdf_2.to_json())
# Add the GeoJSON as a layer to the folium map
folium.GeoJson(
gdf_geojson,
name='GDF Geometry',
style_function=lambda feature: {
'color': 'brown',
'weight': 2,
'fillOpacity': 0.01,
}
).add_to(my_map)
# Add a layer control panel to the map
my_map.add_child(folium.LayerControl())
print(f"Sample dates: {start_date} to {end_date}")
# Display the map
my_map
Sample dates: 2005-01-01 to 2024-01-01
Wildfire Probability¶
import ee
import folium
ee.Initialize()
# Define your geometry here as before. Assuming 'geometry' is an ee.Geometry object.
# # Define the time period
# start_date = '2005-01-01'
# end_date = '2017-05-01'
# Load the dataset and filter
dataset = ee.ImageCollection('MODIS/061/MOD14A1') \
.filter(ee.Filter.date(start_date, end_date)) \
.filterBounds(geometry)
# Use the FireMask band to identify fire locations
fire_locations = dataset.select('FireMask').map(lambda image: image.eq(7).Or(image.eq(8)).Or(image.eq(9)))
# Composite the fire location images to get a single layer
composite_fire_locations = fire_locations.max()
# Visualization parameters for fire locations
fire_locations_vis = {
'min': 0,
'max': 1,
'palette': ['yellow', 'red'] # Yellow for lower confidence fires, red for higher
}
# Centroid for map centering
centroid = geometry.centroid(maxError=1)
lng, lat = centroid.coordinates().getInfo()
# Create a folium map object and center it on the centroid of the geometry
my_map = folium.Map(location=[lat, lng], zoom_start=9)
# Custom method for adding Earth Engine layers to folium map
def add_ee_layer(self, ee_image_object, vis_params, name):
map_id_dict = ee.Image(ee_image_object).getMapId(vis_params)
folium.raster_layers.TileLayer(
tiles=map_id_dict['tile_fetcher'].url_format,
attr='Map Data © <a href="https://earthengine.google.com/">Google Earth Engine</a>',
name=name,
overlay=True,
control=True
).add_to(self)
# Patch the method to folium Map
folium.Map.add_ee_layer = add_ee_layer
# Add the fire locations layer
my_map.add_ee_layer(composite_fire_locations, fire_locations_vis, 'Fire Prone Areas')
# Load your GeoDataFrame
gdf_2 = gpd.read_file(r"C:\Users\rsingh\OneDrive - PlanRVA\Documents\DataHub-Rishabh\Base locality Boundary\Loc_Boundary_RVA_XY.shp")
# Convert GeoDataFrame to GeoJSON
gdf_geojson = json.loads(gdf_2.to_json())
# Add the GeoJSON as a layer to the folium map
folium.GeoJson(
gdf_geojson,
name='GDF Geometry',
style_function=lambda feature: {
'color': 'black',
'weight': 2,
'fillOpacity': 0.01,
}
).add_to(my_map)
# Add a layer control panel to the map
my_map.add_child(folium.LayerControl())
print(f"Sample dates: {start_date} to {end_date}")
# Display the map
my_map
Sample dates: 2005-01-01 to 2024-01-01
## Last updated till here: Start from here next. Try to export map/image/bunchofimages to a raster.
#Date: 02/11/2024
# # Export the composite_fire_locations Image to Google Drive
# export_task = ee.batch.Export.image.toDrive(**{
# 'image': composite_fire_locations,
# 'description': 'FireLocationsComposite',
# 'folder': 'EarthEngineExports',
# 'fileNamePrefix': 'fire_locations_composite',
# 'scale': 500, # Choose an appropriate scale based on your dataset's resolution
# 'region': geometry.bounds(), # Define the region to export based on your area of interest
# 'fileFormat': 'GeoTIFF', # Export format
# 'maxPixels': 1e9 # Increase if you encounter 'too many pixels' error, adjust as needed
# })
# # Start the export task
# export_task.start()
# export_task = ee.batch.Export.image.toDrive(**{
# 'image': composite_fire_locations.visualize(**fire_locations_vis),
# 'description': 'FireLocationsCompositePNG_50',
# 'folder': 'EarthEngineExports',
# 'fileNamePrefix': 'fire_locations_composite_png',
# 'scale': 50,
# 'region': geometry.bounds(),
# 'fileFormat': 'GeoTIFF',
# 'maxPixels': 1e13
# })
# export_task.start()
## More visualizations
from datetime import datetime
# Define the start and end dates
start_date_str = start_date
end_date_str = end_date
# Convert strings to datetime objects
start_date_x = datetime.strptime(start_date_str, '%Y-%m-%d')
end_date_x = datetime.strptime(end_date_str, '%Y-%m-%d')
# Calculate the difference in years
year_difference = end_date_x.year - start_date_x.year - ((end_date_x.month, end_date_x.day) < (start_date_x.month, start_date_x.day))
yd=year_difference
print(year_difference)
19
import ee
import folium
ee.Initialize()
# Define your geometry here as before
import geopandas as gpd
# Assuming gdf_2 is already loaded from your shapefile
# Ensure your GeoDataFrame is in a CRS compatible with Earth Engine, typically EPSG:4326 (latitude, longitude)
# If necessary, convert the CRS to EPSG:4326
gdf_2 = gdf_2.to_crs(epsg=4326)
# Extract the first geometry's coordinates (assuming you're interested in the first feature for simplicity)
# For more complex cases, you might loop through gdf_2.geometry or handle MultiPolygons
geometry = ee_geometry
# # Define the time period
# start_date = '2005-01-01'
# end_date = '2018-05-01'
# Load the dataset and filter
dataset = ee.ImageCollection('MODIS/061/MOD14A1') \
.filter(ee.Filter.date(start_date, end_date)) \
.filterBounds(geometry)
# Summing the MaxFRP values over the time period to get total fire intensity
summed_frp = dataset.select('MaxFRP').sum()
# Function to get the maximum value of the summed FRP over the specified geometry
def get_max_frp(summed_image, geometry, scale=1000):
stats = summed_image.reduceRegion(
reducer=ee.Reducer.max(),
geometry=ee_geometry,
scale=scale,
bestEffort=True
)
return stats.getInfo()['MaxFRP']
max_frp = get_max_frp(summed_frp, geometry)
print('Maximum FRP:', max_frp)
fire_palette = [
'50A2A7', # Cool water color for no or very low fire intensity
'92C1C1', # Slightly warmer, still low intensity
'D9D678', # A greenish-yellow for low to moderate intensity
'D9AE4B', # Yellow for moderate fire intensity
'D9903D', # Orange for high fire intensity
'D84B2A', # Red-orange for very high fire intensity
'A80000' # Dark red for extreme fire intensity
]
# Define visualization parameters for the summed FRP
summed_frp_vis = {
'min': 0,
'max': max_frp*0.1, # Adjust this max value based on the range of your summed FRP values
'palette': fire_palette
}
# Initialize empty lists to store bounding box coordinates
lngs = []
lats = []
# Iterate over each feature in the FeatureCollection
for feature in geometry.getInfo()['features']:
bounds = ee.Geometry(feature['geometry']).bounds().getInfo()
coords = bounds['coordinates'][0] # Extract the coordinates
lngs.extend([coord[0] for coord in coords]) # Extract longitudes
lats.extend([coord[1] for coord in coords]) # Extract latitudes
# Calculate the overall bounding box
min_lng, max_lng = min(lngs), max(lngs)
min_lat, max_lat = min(lats), max(lats)
# Calculate the centroid from the bounding box
lng = (min_lng + max_lng) / 2
lat = (min_lat + max_lat) / 2
# # Centroid for map centering
# centroid = geometry.centroid(maxError=1)
# lng, lat = centroid.coordinates().getInfo()
# Create a folium map object and center it on the centroid of the geometry
my_map = folium.Map(location=[lat, lng], zoom_start=9)
# Define a function to add Earth Engine layers to folium map
def add_ee_layer(self, ee_image_object, vis_params, name):
map_id_dict = ee.Image(ee_image_object).getMapId(vis_params)
folium.raster_layers.TileLayer(
tiles=map_id_dict['tile_fetcher'].url_format,
attr='Map Data © <a href="https://earthengine.google.com/">Google Earth Engine</a>',
name=name,
overlay=True,
control=True
).add_to(self)
# Add custom method to folium map for adding Earth Engine layers
folium.Map.add_ee_layer = add_ee_layer
# Apply the scale factor to summed_frp before visualization
summed_frp_scaled = summed_frp.multiply(0.1)
# Add the summed FRP layer to the map
my_map.add_ee_layer(summed_frp_scaled, summed_frp_vis, 'Summed FRP')
# Load your GeoDataFrame
gdf_2 = gpd.read_file(r"C:\Users\rsingh\OneDrive - PlanRVA\Documents\DataHub-Rishabh\Base locality Boundary\Loc_Boundary_RVA_XY.shp")
# Convert GeoDataFrame to GeoJSON
gdf_geojson = json.loads(gdf_2.to_json())
# Add the GeoJSON as a layer to the folium map
folium.GeoJson(
gdf_geojson,
name='GDF Geometry',
style_function=lambda feature: {
'color': 'brown',
'weight': 2,
'fillOpacity': 0.01,
}
).add_to(my_map)
# Extract center coordinates from the GeoJSON layer
center_coords = folium.GeoJson(gdf_geojson).get_bounds()[0]
# Define the center of the map
lat, lng = center_coords
# Add CartoDB Positron as an additional basemap option
folium.TileLayer('CartoDB positron', name='Light Grey Basemap').add_to(my_map)
import folium
from folium import features
# Create a custom legend
legend_html = """
<div style="
position: fixed;
bottom: 50px;
left: 50px;
width: 200px;
border: 2px solid grey;
z-index: 9999;
font-size: 14px;
font-family: Arial, sans-serif;
background-color: rgba(255, 255, 255, 0.8); /* Translucent background */
border-radius: 10px; /* Rounded corners */
padding: 10px; /* Padding */
box-shadow: 0 2px 5px rgba(0,0,0,0.2); /* Drop shadow */
">
<div style="font-size: 16px; font-weight: bold;">Fire Intensity</div> <!-- Title with different font size -->
<div style="margin-top: 5px;">
<div style="background: #A80000; width: 18px; height: 18px; display: inline-block; margin-right: 5px;"></div> <!-- Color swatch -->
Extreme
</div>
<div style="margin-top: 5px;">
<div style="background: #D84B2A; width: 18px; height: 18px; display: inline-block; margin-right: 5px;"></div> <!-- Color swatch -->
Very High
</div>
<div style="margin-top: 5px;">
<div style="background: #D9903D; width: 18px; height: 18px; display: inline-block; margin-right: 5px;"></div> <!-- Color swatch -->
High
</div>
<div style="margin-top: 5px;">
<div style="background: #D9AE4B; width: 18px; height: 18px; display: inline-block; margin-right: 5px;"></div> <!-- Color swatch -->
Moderate
</div>
<div style="margin-top: 5px;">
<div style="background: #D9D678; width: 18px; height: 18px; display: inline-block; margin-right: 5px;"></div> <!-- Color swatch -->
Low to Moderate
</div>
<div style="margin-top: 5px;">
<div style="background: #92C1C1; width: 18px; height: 18px; display: inline-block; margin-right: 5px;"></div> <!-- Color swatch -->
Low
</div>
<div style="margin-top: 5px;">
<div style="background: #50A2A7; width: 18px; height: 18px; display: inline-block; margin-right: 5px;"></div> <!-- Color swatch -->
Very Low
</div>
</div>
"""
# Add legend as a popup on the map with adjusted position
legend_popup = folium.Marker(
[lat, lng - 0.7], # Shifted coordinates for the legend popup
icon=folium.DivIcon(html=legend_html)
)
# Add the legend popup to the map
my_map.add_child(legend_popup)
# Add a layer control panel to the map
my_map.add_child(folium.LayerControl())
print(f"Sample dates: {start_date} to {end_date}")
# Display the map
my_map
Maximum FRP: 10580 Sample dates: 2005-01-01 to 2024-01-01
Average FRP - averaged by time¶
import ee
import folium
ee.Initialize()
# Define your geometry here as before
import geopandas as gpd
# Assuming gdf_2 is already loaded from your shapefile
# Ensure your GeoDataFrame is in a CRS compatible with Earth Engine, typically EPSG:4326 (latitude, longitude)
# If necessary, convert the CRS to EPSG:4326
gdf_2 = gdf_2.to_crs(epsg=4326)
# Extract the first geometry's coordinates (assuming you're interested in the first feature for simplicity)
# For more complex cases, you might loop through gdf_2.geometry or handle MultiPolygons
geometry = ee_geometry
# # Define the time period
# start_date = '2005-01-01'
# end_date = '2018-05-01'
# Load the dataset and filter
dataset = ee.ImageCollection('MODIS/061/MOD14A1') \
.filter(ee.Filter.date(start_date, end_date)) \
.filterBounds(geometry)
# Summing the MaxFRP values over the time period to get total fire intensity
#summed_frp = dataset.select('MaxFRP').sum()/yd
# Sum 'MaxFRP' over the dataset
summed_frp_image = dataset.select('MaxFRP').reduce(ee.Reducer.sum())
# Normalize the summed FRP by the number of years to get an average annual FRP
average_annual_frp = summed_frp_image.divide(yd)
def get_max_frp(summed_image, geometry, scale=1000):
# Assuming the band might not be named 'MaxFRP' after reduction, we'll use a generic approach.
# Attempt to fetch the first band's name to use in our max reduction.
# This assumes your summed_image has at least one band.
first_band_name = summed_image.bandNames().getInfo()[0]
stats = summed_image.reduceRegion(
reducer=ee.Reducer.max(),
geometry=geometry,
scale=scale,
bestEffort=True
)
# Use the first band name to attempt to fetch the max value from stats
max_value = stats.getInfo().get(first_band_name)
# If the result does not contain the expected band, return a default or handle appropriately
if max_value is None:
print(f"No data found for {first_band_name} in the specified geometry.")
return 0 # Or handle this case as appropriate for your application
return max_value
# Then call `get_max_frp` with your `average_annual_frp` and `ee_geometry`
max_frp = get_max_frp(average_annual_frp, ee_geometry)
print('Maximum average annual FRP:', max_frp)
fire_palette = [
'50A2A7', # Cool water color for no or very low fire intensity
'92C1C1', # Slightly warmer, still low intensity
'D9D678', # A greenish-yellow for low to moderate intensity
'D9AE4B', # Yellow for moderate fire intensity
'D9903D', # Orange for high fire intensity
'D84B2A', # Red-orange for very high fire intensity
'A80000' # Dark red for extreme fire intensity
]
# Define visualization parameters for the summed FRP
summed_frp_vis = {
'min': 0,
'max': max_frp*0.1, # Adjust this max value based on the range of your summed FRP values
'palette': fire_palette
}
# Initialize empty lists to store bounding box coordinates
lngs = []
lats = []
# Iterate over each feature in the FeatureCollection
for feature in geometry.getInfo()['features']:
bounds = ee.Geometry(feature['geometry']).bounds().getInfo()
coords = bounds['coordinates'][0] # Extract the coordinates
lngs.extend([coord[0] for coord in coords]) # Extract longitudes
lats.extend([coord[1] for coord in coords]) # Extract latitudes
# Calculate the overall bounding box
min_lng, max_lng = min(lngs), max(lngs)
min_lat, max_lat = min(lats), max(lats)
# Calculate the centroid from the bounding box
lng = (min_lng + max_lng) / 2
lat = (min_lat + max_lat) / 2
# # Centroid for map centering
# centroid = geometry.centroid(maxError=1)
# lng, lat = centroid.coordinates().getInfo()
# Create a folium map object and center it on the centroid of the geometry
my_map = folium.Map(location=[lat, lng], zoom_start=9)
# Define a function to add Earth Engine layers to folium map
def add_ee_layer(self, ee_image_object, vis_params, name):
map_id_dict = ee.Image(ee_image_object).getMapId(vis_params)
folium.raster_layers.TileLayer(
tiles=map_id_dict['tile_fetcher'].url_format,
attr='Map Data © <a href="https://earthengine.google.com/">Google Earth Engine</a>',
name=name,
overlay=True,
control=True
).add_to(self)
# Add custom method to folium map for adding Earth Engine layers
folium.Map.add_ee_layer = add_ee_layer
# Apply the scale factor to summed_frp before visualization
summed_frp_scaled = summed_frp.multiply(0.1)
# Add the summed FRP layer to the map
my_map.add_ee_layer(summed_frp_scaled, summed_frp_vis, 'Summed FRP')
# Load your GeoDataFrame
gdf_2 = gpd.read_file(r"C:\Users\rsingh\OneDrive - PlanRVA\Documents\DataHub-Rishabh\Base locality Boundary\Loc_Boundary_RVA_XY.shp")
# Convert GeoDataFrame to GeoJSON
gdf_geojson = json.loads(gdf_2.to_json())
# Add the GeoJSON as a layer to the folium map
folium.GeoJson(
gdf_geojson,
name='GDF Geometry',
style_function=lambda feature: {
'color': 'brown',
'weight': 2,
'fillOpacity': 0.01,
}
).add_to(my_map)
# Extract center coordinates from the GeoJSON layer
center_coords = folium.GeoJson(gdf_geojson).get_bounds()[0]
# Define the center of the map
lat, lng = center_coords
# Add CartoDB Positron as an additional basemap option
folium.TileLayer('CartoDB positron', name='Light Grey Basemap').add_to(my_map)
import folium
from folium import features
# Create a custom legend
legend_html = f"""
<div style="
position: fixed;
bottom: 50px;
left: 50px;
width: 200px;
border: 2px solid grey;
z-index: 9999;
font-size: 14px;
font-family: Arial, sans-serif;
background-color: rgba(255, 255, 255, 0.8); /* Translucent background */
border-radius: 10px; /* Rounded corners */
padding: 10px; /* Padding */
box-shadow: 0 2px 5px rgba(0,0,0,0.2); /* Drop shadow */
">
<div style="font-size: 16px; font-weight: bold;">Average Fire Intensity</div>
<!-- Smaller and lighter date text -->
<div style="font-size: 12px; color: #888;">({start_date} to {end_date})</div>
<div style="margin-top: 5px;">
<div style="background: #A80000; width: 18px; height: 18px; display: inline-block; margin-right: 5px;"></div> Extreme
</div>
<div style="margin-top: 5px;">
<div style="background: #D84B2A; width: 18px; height: 18px; display: inline-block; margin-right: 5px;"></div> Very High
</div>
<div style="margin-top: 5px;">
<div style="background: #D9903D; width: 18px; height: 18px; display: inline-block; margin-right: 5px;"></div> High
</div>
<div style="margin-top: 5px;">
<div style="background: #D9AE4B; width: 18px; height: 18px; display: inline-block; margin-right: 5px;"></div> Moderate
</div>
<div style="margin-top: 5px;">
<div style="background: #D9D678; width: 18px; height: 18px; display: inline-block; margin-right: 5px;"></div> Low to Moderate
</div>
<div style="margin-top: 5px;">
<div style="background: #92C1C1; width: 18px; height: 18px; display: inline-block; margin-right: 5px;"></div> Low
</div>
<div style="margin-top: 5px;">
<div style="background: #50A2A7; width: 18px; height: 18px; display: inline-block; margin-right: 5px;"></div> Very Low
</div>
</div>
"""
# Add legend as a popup on the map with adjusted position
legend_popup = folium.Marker(
[lat, lng - 0.7], # Shifted coordinates for the legend popup
icon=folium.DivIcon(html=legend_html)
)
# Add the legend popup to the map
my_map.add_child(legend_popup)
# Add a layer control panel to the map
my_map.add_child(folium.LayerControl())
print(f"Sample dates: {start_date} to {end_date}")
# Display the map
my_map
Maximum average annual FRP: 556.8421052631579 Sample dates: 2005-01-01 to 2024-01-01
#########
Wildfire Probability Map: Added Legend and different color palette¶
import ee
import folium
ee.Initialize()
# Define your geometry here as before
# # Define the time period
# start_date = '2005-01-01'
# end_date = '2018-05-01'
# Load the dataset and filter
dataset = ee.ImageCollection('MODIS/061/MOD14A1') \
.filter(ee.Filter.date(start_date, end_date)) \
.filterBounds(geometry)
# Summing the MaxFRP values over the time period to get total fire intensity
summed_frp = dataset.select('FireMask')
# Use the FireMask band to identify fire locations
fire_locations = dataset.select('FireMask').map(lambda image: image.eq(7).Or(image.eq(8)).Or(image.eq(9)))
# Composite the fire location images to get a single layer
composite_fire_locations = fire_locations.max()
# Visualization parameters for fire locations
fire_locations_vis = {
'min': 0,
'max': 1,
'palette': ['#90EE9010', '#FF000080'] # Yellow for lower confidence fires, red for higher
}
# Initialize empty lists to store bounding box coordinates
lngs = []
lats = []
# Iterate over each feature in the FeatureCollection
for feature in geometry.getInfo()['features']:
bounds = ee.Geometry(feature['geometry']).bounds().getInfo()
coords = bounds['coordinates'][0] # Extract the coordinates
lngs.extend([coord[0] for coord in coords]) # Extract longitudes
lats.extend([coord[1] for coord in coords]) # Extract latitudes
# Calculate the overall bounding box
min_lng, max_lng = min(lngs), max(lngs)
min_lat, max_lat = min(lats), max(lats)
# Calculate the centroid from the bounding box
lng = (min_lng + max_lng) / 2
lat = (min_lat + max_lat) / 2
# # Centroid for map centering
# centroid = geometry.centroid(maxError=1)
# lng, lat = centroid.coordinates().getInfo()
# Create a folium map object and center it on the centroid of the geometry
my_map = folium.Map(location=[lat, lng], zoom_start=9)
# Custom method for adding Earth Engine layers to folium map
def add_ee_layer(self, ee_image_object, vis_params, name):
map_id_dict = ee.Image(ee_image_object).getMapId(vis_params)
folium.raster_layers.TileLayer(
tiles=map_id_dict['tile_fetcher'].url_format,
attr='Map Data © <a href="https://earthengine.google.com/">Google Earth Engine</a>',
name=name,
overlay=True,
control=True
).add_to(self)
# Patch the method to folium Map
folium.Map.add_ee_layer = add_ee_layer
# Add the fire locations layer
my_map.add_ee_layer(composite_fire_locations, fire_locations_vis, 'Fire Prone Areas')
# Load your GeoDataFrame
gdf_2 = gpd.read_file(r"C:\Users\rsingh\OneDrive - PlanRVA\Documents\DataHub-Rishabh\Base locality Boundary\Loc_Boundary_RVA_XY.shp")
# Convert GeoDataFrame to GeoJSON
gdf_geojson = json.loads(gdf_2.to_json())
# Add the GeoJSON as a layer to the folium map
folium.GeoJson(
gdf_geojson,
name='GDF Geometry',
style_function=lambda feature: {
'color': 'brown',
'weight': 2,
'fillOpacity': 0.01,
}
).add_to(my_map)
# Add CartoDB Positron as an additional basemap option
folium.TileLayer('CartoDB positron', name='Light Grey Basemap').add_to(my_map)
#folium.TileLayer('Stamen Toner Lite', name='Light Grey Basemap_2').add_to(my_map)
# Adjusted legend HTML with enhanced styles
legend_html = f"""
<div style="
position: fixed;
bottom: 50px;
left: 50px;
width: 200px;
border: 2px solid grey;
z-index: 9999;
font-size: 14px;
font-family: Arial, sans-serif;
background-color: rgba(255, 255, 255); /* Translucent background */
border-radius: 10px; /* Rounded corners */
padding: 10px; /* Padding */
box-shadow: 0 2px 5px rgba(0,0,0,0.2); /* Drop shadow */
">
<div style="font-size: 16px; font-weight: bold;">WildFire Probability</div>
<!-- Smaller and lighter date text -->
<div style="font-size: 12px; color: #888;">({start_date} to {end_date})</div>
<div style="margin-top: 5px;">
<div style="margin-top: 5px;">
<div style="background: #FF0000; width: 18px; height: 18px; display: inline-block; margin-right: 5px;"></div> <!-- Color swatch -->
Wildfire Prone Areas
</div>
</div>
"""
# Add legend as a popup on the map with adjusted position
legend_popup = folium.Marker(
[lat + 0.4, lng - 1.2], # Shifted coordinates for the legend popup
icon=folium.DivIcon(html=legend_html)
)
# Add the legend popup to the map
my_map.add_child(legend_popup)
# Add a layer control panel to the map
my_map.add_child(folium.LayerControl())
print(f"Sample dates: {start_date} to {end_date}")
# Display the map
my_map
Sample dates: 2005-01-01 to 2024-01-01
## Can also try to reduceresize firemask to give importance to the temporal dimension
## Start Next time
import ee
import json
# Authenticate with Earth Engine
ee.Authenticate()
# Open the authentication file and read the token
with open(ee.oauth.get_credentials_path()) as f:
credentials = json.load(f)
token = credentials['refresh_token'] # The access token is stored under 'refresh_token'
# Print the token
print("Authentication token:", token)
# import requests
# # GitHub username and personal access token
# username = 'planwithdata'
# token = 'dXChaMViBCgYIARAAGAUSNwF-L9IrOp3Dv9rtLEm5QVcTqc-tMjJjrbFDbdd3GDisju-S72njWAp8n3Ju88cFKVy-uIIroNs'
# # Repository name
# repo_name = 'Projects'
# # Create a new repository
# url = f'https://api.github.com/user/repos'
# headers = {
# 'Authorization': f'token {token}',
# 'Accept': 'application/vnd.github.v3+json'
# }
# data = {
# 'name': repo_name,
# 'private': True, # Set to True for a private repository
# }
# response = requests.post(url, headers=headers, json=data)
# # Check if the repository was created successfully
# if response.status_code == 201:
# print(f"Repository '{repo_name}' created successfully!")
# print(f"URL: {response.json()['html_url']}")
# else:
# print(f"Failed to create repository. Status code: {response.status_code}")
# print(response.json())
ub:
import os
os.getcwd()
Create New Notebook and close the current one after committing to git¶
## Working Git script
from nbformat import read, write
from datetime import datetime
import os
import re
import ipynbname
# To get the full path of the current notebook
nb_path = ipynbname.path()
print(nb_path)
current_notebook_path = nb_path
# Read the current notebook
with open(current_notebook_path, "r", encoding="utf-8") as f:
notebook = read(f, as_version=4)
# Modify the regex to capture only the necessary part of the filename (up to the first date)
match = re.search(r'^(.*?)_\d{4}-\d{2}-\d{2}', os.path.basename(current_notebook_path))
if match:
# Capture the base part of the filename without the datetime
base_part = match.group(1)
else:
raise ValueError("Base part of filename not found")
# Get the current datetime
current_datetime = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
# Create the new notebook filename with the base part and the current datetime
new_notebook_filename = f"{base_part}_{current_datetime}.ipynb"
# Save the notebook with outputs intact
with open(new_notebook_filename, "w", encoding="utf-8") as f:
write(notebook, f)
# Output the new notebook filename
new_notebook_filename
Above script finalized.
#!git branch #If you're unsure about the branch name, you can check the list of branches using:
!git add {new_notebook_filename}
!git status
!git commit -m "Created Average FRP plot by averaging temporaly and corrected git script"
!git push origin master #For example, if your branch is named "master", you should use
import os
# Open the new notebook
os.system(f'jupyter notebook {new_notebook_filename}')
# Exit the current notebook
quit()